home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1998 / MacHack 1998.toast / Programming Contest / Secret Solutions Folder / Problem 07 - Graph / Solution.p < prev   
Encoding:
Text File  |  1998-06-13  |  4.4 KB  |  149 lines  |  [TEXT/CWIE]

  1. (*
  2. Problem 07 - Graph
  3.  
  4. procedure GraphInit( var graph: Handle; verrticies: UInt32 );
  5. procedure GraphAddDirectedEdge( graph: Handle; vertex1, vertex2: UInt32 );
  6. procedure GraphFindRoute( graph: Handle; vertex1, vertex2: UInt32; var verticies: Handle );
  7.  
  8. GraphInit creates a new, empty directed graph ready to accept directed edges with verrticies verrticies.  All the graph information must be stored in the real Mac memory manager handle - it will be disposed with DisposeHandle and that must release all memory, so dont store any extra information outside the handle.  Also, you must be able to deal with having multiple graphs instantiated simultaneously.
  9.  
  10. GraphAddDirectedEdge adds a directed edge from vertex1 to vertex2
  11.  
  12. GraphFindRoute find a route from vertex1 to vertex2.  If such a route exists, then verticies is returns as a real Mac handle to an array of UInt32s, the first is vertex1, the last is vertex2.  Each successive vertex must have previously had an edge added with GraphAddDirectedEdge.  If no route exists, return nil for verticies.  No vertex should appear more than once in the verticies handle, except for the case where vertex1 is the same as vertex2, in which case you must find a circular route from vertex1 back to itself and so vertex1 will appear exactly twice, once at the start and once at the end of the verticies handle.
  13. *)
  14.  
  15. unit Solution;
  16.  
  17. interface
  18.  
  19. // Do not modify the interface
  20.  
  21.     uses
  22.         Types, Files;
  23.         
  24.     type
  25.         UInt32Array = array[0..0] of UInt32;
  26.         UInt32ArrayPtr = ^UInt32Array;
  27.         UInt32ArrayHandle = ^UInt32ArrayPtr;
  28.  
  29.     procedure GraphInit( var graph: Handle; verticies: UInt32 );
  30.     procedure GraphAddDirectedEdge( graph: Handle; vertex1, vertex2: UInt32 );
  31.     procedure GraphFindRoute( graph: Handle; vertex1, vertex2: UInt32; var verticies: UInt32ArrayHandle );
  32.  
  33. implementation
  34.  
  35. // Fill in your solution and then submit this folder
  36.  
  37. // Team Name: Example Solution
  38. // 15:25
  39. // 15:42
  40. // 15:49
  41. // 15:55
  42.  
  43.     uses
  44.         ToolUtils;
  45.  
  46.     function GetVerticies( graph: Handle ): UInt32;
  47.     begin
  48.         GetVerticies := UInt32ArrayHandle(graph)^^[0];
  49.     end;
  50.     
  51.     function GetBitArrayStart( graph: Handle ): Ptr;
  52.     begin
  53.         GetBitArrayStart := Ptr(longint(graph^)+(1 + GetVerticies(graph))*4);
  54.     end;
  55.     
  56.     procedure SetABit( graph: Handle; v1, v2: UInt32 );
  57.     begin
  58.         BitSet( GetBitArrayStart( graph ),(v1-1) * GetVerticies(graph) + (v2-1) );
  59.     end;
  60.     
  61.     function TestABit( graph: Handle; v1, v2: UInt32 ): boolean;
  62.     begin
  63.         TestABit := BitTst( GetBitArrayStart( graph ),(v1-1) * GetVerticies(graph) + (v2-1) );
  64.     end;
  65.     
  66.     procedure GraphInit( var graph: Handle; verticies: UInt32 );
  67.     begin
  68.         graph := NewHandleClear( (1 + verticies) * 4 + verticies * verticies div 8 + 1 );
  69.         if graph <> nil then begin
  70.             UInt32ArrayHandle(graph)^^[0] := verticies;
  71.         end;
  72.     end;
  73.     
  74.     procedure GraphAddDirectedEdge( graph: Handle; vertex1, vertex2: UInt32 );
  75.     begin
  76.         HLock( graph );
  77.         SetABit( graph, vertex1, vertex2 );
  78.         HUnlock( graph );
  79.     end;
  80.     
  81.     procedure GraphFindRoute( graph: Handle; vertex1, vertex2: UInt32; var verticies: UInt32ArrayHandle );
  82.         const
  83.             no_route = $7FFFFFFF;
  84.         var
  85.             count, routecount: UInt32;
  86.             counts: UInt32ArrayPtr;
  87.             i, j, k: UInt32;
  88.             continue: boolean;
  89.     begin
  90.         HLock( graph );
  91.         count := GetVerticies( graph );
  92.         counts := UInt32ArrayHandle(graph)^;
  93.         
  94.         // Initialize counts
  95.         for i := 1 to count do begin
  96.             if TestABit( graph, vertex1, i ) then begin
  97.                 counts^[i] := 1;
  98.             end else begin
  99.                 counts^[i] := no_route;
  100.             end;
  101.         end;
  102.         
  103.         // Flood fill
  104.         for i := 1 to count do begin
  105.             if counts^[vertex2] <> no_route then begin
  106.                 leave;
  107.             end;
  108.             continue := false;
  109.             for j := 1 to count do begin
  110.                 if counts^[j] = i then begin
  111.                     for k := 1 to count do begin
  112.                         if (counts^[k] = no_route) & TestABit( graph, j, k ) then begin
  113.                             counts^[k] := i + 1;
  114.                             continue := true;
  115.                         end;
  116.                     end;
  117.                 end;
  118.             end;
  119.             if not continue then begin
  120.                 leave;
  121.             end;
  122.         end;
  123.         
  124.         // Answer
  125.         if counts^[vertex2] = no_route then begin
  126.             verticies := nil;
  127.         end else begin
  128.             routecount := counts^[vertex2];
  129.             verticies := UInt32ArrayHandle( NewHandleClear( (routecount + 1) * 4 ));
  130.             if verticies <> nil then begin
  131.                 verticies^^[0] := vertex1;
  132.                 verticies^^[routecount] := vertex2;
  133.                 for i := routecount-1 downto 1 do begin
  134.                     for j := 1 to count do begin
  135.                         if TestABit( graph, j, vertex2 ) & (counts^[j] = i) then begin
  136.                             verticies^^[i] := j;
  137.                             vertex2 := j;
  138.                             leave;
  139.                         end;
  140.                     end;
  141.                 end;
  142.             end;
  143.         end;
  144.         
  145.         HUnlock( graph );
  146.     end;
  147.  
  148. end.
  149.